#pragma once

#include<iostream>
#include<math.h>

using namespace std;

template<class T>
class interval
{
private:
	T upper;
	T lower;


public:

	interval(void)
	{
		upper=0;
		lower=0;
	}

	interval(T tal, double procent)
	{
		lower=tal - tal * procent / 100;
		upper=tal + tal * procent / 100;
	}

	double getUpper()
	{return upper;}

	T medel()
	{
		return (upper+lower)/2; 
	}

	double absolute_error()
	{
		return (upper-lower)/medel();
	}

	double procentual_error()
	{
		return (upper-lower)/medel()*100;
	}

	friend interval<T> operator+(interval<T> &lop, interval<T> &rop )
	{
		interval<T> e;

		e.upper = lop.upper+rop.upper;
		e.lower = lop.lower+rop.lower;
		return e;
	}

	friend interval<T> operator-(interval<T> &lop, interval<T> &rop )
	{
		interval<T> e;

		e.upper = lop.lower-rop.upper;
		e.lower = lop.upper-rop.lower;
		return e;
	}

	friend interval<T> operator*(interval<T> &lop, interval<T> &rop )
	{
		interval<T> e;
		e.upper=max(max(lop.upper*rop.upper,lop.upper*rop.lower),max(lop.lower*rop.upper,lop.lower*rop.lower));
		e.lower=min(min(lop.upper*rop.upper,lop.upper*rop.lower),min(lop.lower*rop.upper,lop.lower*rop.lower));
		return e;
	}

	friend interval<T> operator/(interval<T> &lop, interval<T> &rop )
	{
		interval<T> e;
		if(rop.upper==0 || rop.lower==0)
			cout << "Fel, division by zero?" << endl;
		else
		{
			e.upper=max(max(lop.upper/rop.upper,lop.upper/rop.lower),max(lop.lower/rop.upper,lop.lower/rop.lower));
			e.lower=min(min(lop.upper/rop.upper,lop.upper/rop.lower),min(lop.lower/rop.upper,lop.lower/rop.lower));
			return e;
		}
	}



	friend ostream& operator<<(ostream &o, const interval<T> &rop)
	{
		if(rop.upper>rop.lower)
		{
			o << "[" << rop.lower << "," << rop.upper << "]";
		}
		else
		{
			o << "[" << rop.upper << "," << rop.lower << "]";
		}
		return o;
	}



	~interval(void)
	{
	}
};

